//
//  WmcSelectAddressVM.swift
//  YPWatermarkCamera
//
//  Created by 周诗松 on 2022/4/9.
//

import AMapSearchKit
import CoreLocation
import Foundation
import RxRelay
import AMapSearchKit

class WmcSelectAddressVM: WmcBaseVM {
    // Internal

    class CustomLocationModel {
        /// 定位
        var location: CLLocation?
        /// 逆地理编码
        var reGeocode: AMapReGeocode?
        /// 地址前缀
        var addressPrefix: String?
        /// 地址前缀列表
        var addressPrefixList: [String] = []
        /// 已选中的地址
        var selectedAddress: WmcSelectAddressModel?
        /// 拍摄的地址
        var takePhotoAddress: WmcSelectAddressModel?
        /// poi列表
        var poiList: [WmcSelectAddressModel] = []
    }

    /// 搜索关键字
    var searchKeyword: String?

    /// 是否需要显示设置常用地址
    var isShowSetCommonAddress: Bool = false

    /// 是否还有数据
    private(set) var hasNoMore: Bool = false

    /// 数据源
    private(set) lazy var dataSource: [WmcSelectAddressModel] = []

    /// 页码
    private(set) lazy var poiPageIndex: Int = 1

    /// 每页条数（高德最大只支持25）
    private(set) lazy var poiPageSize: Int = 25

    /// 方圆多少米
    private(set) lazy var poiRadius: Int = 200

    /// 定位信息
    var customLocation: CustomLocationModel?

    /// 选择地址
    var selectAddress: ((WmcSelectAddressModel) -> Void)?

    /// 刷新
    func refresh(completion: @escaping ([WmcSelectAddressModel]) -> Void, failure: @escaping (Error?) -> Void) {
        if customLocation == nil {
            location = WmcLocationManager.shared.locationStatus.value?.data?.location
            reGeocode = WmcLocationManager.shared.locationStatus.value?.data?.reGeocode
        }
        
        queryCustomAddress(completion: { [weak self] customAddressList in
            guard let weakSelf = self else { return }
            
            guard let location = weakSelf.location else {
                failure(nil)
                var dataSource = customAddressList
                if let addCustomAddressModel = weakSelf.createAddCustomAddress(list: dataSource) {
                    dataSource.append(addCustomAddressModel)
                }
                weakSelf.dataSource = dataSource
                completion(weakSelf.dataSource)
                return
            }
            
            WmcLocationManager.searchPoiByKeyword(weakSelf.searchKeyword, pageIndex: 1, pageSize: weakSelf.poiPageSize, location: location, radius: weakSelf.poiRadius) { [weak self] list in
                guard let weakSelf = self else { return }

                weakSelf.poiPageIndex = 2
                weakSelf.hasNoMore = list.count < weakSelf.poiPageSize

                var temp = customAddressList
                temp.append(contentsOf: list)

                // 排序
                let poiList = WmcLocationManager.sortCommonlyAddressList(temp)
                
                let selectedAddress = weakSelf.customLocation == nil ? WmcLocationManager.shared.poiStatus.value?.data : weakSelf.customLocation?.selectedAddress
            
                // 设置选中的
                var dataSource = WmcLocationManager.setSelectedAddress(array: poiList, selectedPOI: selectedAddress)
                
                // 最后一行是否显示【添加自定义】
                if let addCustomAddressModel = weakSelf.createAddCustomAddress(list: dataSource) {
                    dataSource.append(addCustomAddressModel)
                }
                weakSelf.dataSource = dataSource

                completion(weakSelf.dataSource)
            } failure: { error in
                var dataSource = customAddressList
                if let addCustomAddressModel = weakSelf.createAddCustomAddress(list: dataSource) {
                    dataSource.append(addCustomAddressModel)
                }
                weakSelf.dataSource = dataSource
                failure(error)
            }
        })
    }

    func loadMore(completion: @escaping ([WmcSelectAddressModel]) -> Void, failure: @escaping (Error?) -> Void) {
        guard let location = location else {
            failure(nil)
            return WmcHudManager.toast("未获取到当前位置")
        }

        WmcLocationManager.searchPoiByKeyword(searchKeyword, pageIndex: poiPageIndex, pageSize: poiPageSize, location: location, radius: poiRadius) { [weak self] list in
            guard let weakSelf = self else { return }

            weakSelf.poiPageIndex += 1
            weakSelf.hasNoMore = list.count < weakSelf.poiPageSize

            var poiList = weakSelf.dataSource
            poiList.append(contentsOf: list)
            poiList = WmcLocationManager.sortCommonlyAddressList(poiList)
            
            let selectedAddress = weakSelf.customLocation == nil ? WmcLocationManager.shared.poiStatus.value?.data : weakSelf.customLocation?.selectedAddress
            
            var dataSource = WmcLocationManager.setSelectedAddress(array: poiList, selectedPOI: selectedAddress)
            dataSource = weakSelf.removeAddCustomAddress(list: dataSource)
            if let addCustomAddressModel = weakSelf.createAddCustomAddress(list: dataSource) {
                dataSource.append(addCustomAddressModel)
            }
            weakSelf.dataSource = dataSource

            completion(weakSelf.dataSource)
        } failure: { error in
            failure(error)
        }
    }

    func sortList() {
        let poiList = WmcLocationManager.sortCommonlyAddressList(dataSource)
        var selectedPOI = WmcLocationManager.shared.poiStatus.value?.data
        if customLocation != nil {
            selectedPOI = customLocation?.selectedAddress
        }
        dataSource = WmcLocationManager.setSelectedAddress(array: poiList, selectedPOI: selectedPOI)
    }

    // Private

    private lazy var location: CLLocation? = {
        return customLocation?.location
    }()
    
    private lazy var reGeocode: AMapReGeocode? = {
        return customLocation?.reGeocode
    }()
    
    func delCustomAddress(_ index: Int) {
        if index < dataSource.count {
            dataSource.remove(at: index)
        }
    }

    // Private

    /// 查询自定义地址
    /// - Returns: 自定义地址列表
    private func queryCustomAddress(completion: @escaping ([WmcSelectAddressModel]) -> Void) {
        var customAddressList: [WmcSelectAddressModel] = []
        WmcCustomAddressDBManager.query { list in
            list.forEach { model in
                let poi: AMapPOI = .init()
                poi.location = AMapGeoPoint.location(withLatitude: model.latitude, longitude: model.longitude)
                poi.uid = model.uid
                poi.name = model.name
                poi.address = model.address
                poi.province = model.province
                poi.city = model.city
                poi.district = model.district
                let addressModel = WmcSelectAddressModel()
                addressModel.poi = poi
                addressModel.style = .customized
                
                if let keyword = self.searchKeyword, !keyword.isEmpty {
                    if model.name.contains(keyword) {
                        customAddressList.append(addressModel)
                    }
                } else {
                    customAddressList.append(addressModel)
                }
            }
            completion(customAddressList)
        }
    }

    /// 创建自定义地址的模型
    /// - Parameter list: 地址数组
    /// - Returns: 新建的model
    private func createAddCustomAddress(list: [WmcSelectAddressModel]) -> WmcSelectAddressModel? {
        guard let keyword = searchKeyword else { return nil }
        
        var isContain: Bool = false
        
        for (_, model) in list.enumerated() {
            if let name = model.poi.name, name == keyword {
                isContain = true
                break
            }
        }
        
        if isContain {
            return nil
        }
        
        let poi: AMapPOI = .init()
        poi.uid = UUID().uuidString
        poi.name = keyword
        poi.distance = 0
        
        if let location = location {
            poi.location = AMapGeoPoint.location(withLatitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
        }
        
        if let reGeocode = reGeocode {
            poi.address = reGeocode.addressComponent.township ?? ""
            poi.province = reGeocode.addressComponent.province ?? ""
            poi.city = reGeocode.addressComponent.city ?? ""
            poi.district = reGeocode.addressComponent.district ?? ""
        }
                
        let addressModel = WmcSelectAddressModel()
        addressModel.poi = poi
        addressModel.style = .settingCustom

        return addressModel
    }
    
    /// 从数组中删除新增自定义地址模型
    /// - Parameter list: 数组
    /// - Returns: 结果
    private func removeAddCustomAddress(list: [WmcSelectAddressModel]) -> [WmcSelectAddressModel] {
        var result: [WmcSelectAddressModel] = []
        list.forEach { model in
            if model.style != .settingCustom {
                result.append(model)
            }
        }
        return result
    }
}
